////////////////////////////////////////////////////////////////////////////////
//
//  FLEX USER GROUP HOKURIKU
//  Copyright 2009 Flex User Group Hokuriku
//  All Rights Reserved.
// 
//  NOTICE: Flex User Group Hokuriku permits you to use, 
//  modify, and distribute this file 
//  in accordance with the terms of the license agreement accompanying it.
//
////////////////////////////////////////////////////////////////////////////////
package net.fxug.hokuriku.chocolat.utils
{
    import com.adobe.air.logging.FileTarget;
    import com.adobe.utils.ArrayUtil;
    
    import flash.errors.IllegalOperationError;
    import flash.filesystem.File;
    import flash.utils.getQualifiedClassName;
    
    import mx.logging.ILogger;
    import mx.logging.Log;
    import mx.logging.targets.LineFormattedTarget;
    import mx.logging.targets.TraceTarget;
    
    import net.fxug.hokuriku.chocolat.logging.WindowTarget;
    import net.fxug.hokuriku.chocolat.logging.constants.LoggingConstants;

    /**
     * ロギング関連のユーティリティクラス
	 * TODO 外部からのロギングレベル、includeプロパティの制御
     * @author hikaruworld
     */
    public class LoggingUtil
    {
//        private static const TRACE_TARGET:String = "-tarce";
//        private static const FILE_TARGET:String = "-file";
        /** デバッグウィンドウ有効化文字列 */
        private static const WINDOW_TARGET:String = "-window";

        /**
         * デフォルトコンストラクタ.
         * @throws IllegalOperationError インスタンス生成が行われた場合にthrowされます。
         */
		[Deprecated("インスタンス化禁止")]
        public function LoggingUtil()
        {
            throw new IllegalOperationError("このクラスのインスタンス化は許可されていません。");
        }

        /**
         * ロガーにクラスの完全名を付与して返す。
         * @param value クラス
         * @return クラスの完全名が設定されたILoggerクラス
         *
		 * @copy mx.logging.Log#getLogger()
		 * @see mx.logging.ILogger
         */
        public static function getLogger(value:*):ILogger
        {
            return Log.getLogger(getQualifiedLoggingClassName(value));
        }

        /**
         * デフォルトとなるロギング設定を行う。
		 * FIXME デフォルと設定はユーザにより出力制御できない。
         */
        public static function setDefaultTarget():void
        {
			var file:File = new File(LoggingConstants.ERROR_LOG_FILE_NAME);
            var fileTarget:FileTarget = new FileTarget(file);
            var traceTarget:TraceTarget = new TraceTarget();

            LoggingUtil.includeTargetValue(fileTarget);
            LoggingUtil.includeTargetValue(traceTarget);
            Log.addTarget(fileTarget);
            Log.addTarget(traceTarget);
        }

        /**
         * Targetの設定を行う。
         * FIXME 本来はここに渡される値をkey=value形式にしてコマンドライン引数からロギング設定を制御できるようにする。
         * @param args 有効にするターゲットクラス
         */
        public static function setTarget(args:Array):void
        {
            if (args == null)
            {
                return;
            }
            var enable:Boolean = ArrayUtil.arrayContainsValue(args, WINDOW_TARGET);
            if (enable)
            {
                var windowTarget:WindowTarget = new WindowTarget();
                LoggingUtil.includeTargetValue(windowTarget);
                Log.addTarget(windowTarget);
            }
        }

        /**
         * Targetのロギング出力設定を行う。
         * @param target 処理対象のTargetクラス
         * @param category カテゴリー
         * @param date 日付
         * @param level レベル
         * @param time 時間
         */
        private static function includeTargetValue(target:LineFormattedTarget, category:Boolean = true, date:Boolean = true, level:Boolean = true, time:Boolean = true):void
        {
            if (target == null)
            {
                throw new ArgumentError("target::のインスタンスが存在しません。");
            }
            target.includeCategory = category;
            target.includeDate = date;
            target.includeLevel = level;
            target.includeTime = time;
        }

        /**
         * getQualifiedClassNameと異なり、パッケージ名とクラス名の接続文字列が、<code>::</code>ではなく<code>.</code>で連結される。
         * @copy flash.utils.#getQualifiedClassName()
         */
        private static function getQualifiedLoggingClassName(value:*):String
        {
            return getQualifiedClassName(value).replace("::", ".");
        }
    }
}